package net.chrisrichardson.ec2deployer.core

import org.apache.commons.logging.*
import org.apache.commons.lang.builder.EqualsBuilder
import org.apache.commons.lang.builder.HashCodeBuilder


class EC2InstanceState {

    Log logger = LogFactory.getLog(getClass())
    String instanceId
    private String state
    private String publicDnsName
    private String privateDnsName
    String availabilityZone
    String imageId

    boolean equals(Object other) {
        return EqualsBuilder.reflectionEquals(this, other)
    }

    public int hashCode() {
      return HashCodeBuilder.reflectionHashCode(this)
    }

    protected EC2InstanceState() {}

    EC2InstanceState(instanceId, imageId, state, availabilityZone) {
        this.instanceId = instanceId
        this.imageId = imageId
        this.state = state
        this.availabilityZone  = availabilityZone
    }

    synchronized String getState() {
        state
    }

    synchronized String getPublicDnsName() {
        publicDnsName
    }

    synchronized String getPrivateDnsName() {
        privateDnsName
    }

    public synchronized updateStatus(newState, publicDnsName, privateDnsName) {
        def oldState = this.state
        this.state = newState;
        this.publicDnsName = publicDnsName
        this.privateDnsName = privateDnsName
        if (oldState != newState) {
            logger.debug("state changed from $oldState to $state")
            this.notifyAll()
        }
    }

    def synchronized waitUntilRunning() {
        while (!isRunning()) {
            assert isAvailable()
            logger.debug "waiting for host: $instanceId, $state"
            wait()
            logger.debug "done waiting for host: $instanceId, $state"
        }
    }

    public synchronized boolean isRunning() {
        state == "running"
    }

    public synchronized boolean isTerminated() {
        state == "terminated"
    }

    public synchronized boolean isAvailable() {
        ["pending", "running"].contains(state)
    }

}